package model.workersWithData;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;

import model.workersWithData.sort.SortOrderByDeadlineDate;

import org.apache.log4j.Logger;

import api.entitites.IGarage;
import api.entitites.IMaster;
import api.entitites.IOrder;
import api.entitites.OrderStatus;

public class WorkerWithOrder {

	private static SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
	private static final String ORD_STAT_NOT_FOUND = "Sorry, orders with this status not found";
	private static final String ORD_EXISTS = "Sorry, order with this number already exists. Order have number: ";
	private static final String ORD_NOT_EXISTS = "Sorry , order with this number is absent";
	private static final String EXCEPTION_CLONE = "Sorry, impossible clone this object";
	private static final Logger log = Logger.getLogger(WorkerWithOrder.class);
	private static final String EMPTY_COLLEC="Collection is empty";
	private static final String NOT_ORDER = "Sorry, no order";

	
	public static IMaster getMastersByOrder(Integer numberOrder,
			ArrayList<IOrder> ordList) {
		try {
			IMaster master=null;
			for (IOrder o : ordList) {
				if (o.getNumberOrder() == numberOrder){
					master=o.getMaster();
				}
			}
			
			if (master != null) {
				return master;
			} else {
				throw new RuntimeException(ORD_NOT_EXISTS);
			}
		} catch (NullPointerException ne) {
			log.warn(EMPTY_COLLEC);
			throw new RuntimeException(NOT_ORDER);
		}
	}

	
	public static ArrayList<IOrder> getListMadingOrder(ArrayList<IOrder> orderList,
			Comparator sortby) {
		try {
			ArrayList<IOrder> ordList = new ArrayList<IOrder>();
			Date date = new Date();
			for (IOrder ord : orderList) {
				if (ord.getBeginingDate().before(date)
						&& ord.getDeadlineDate().after(date)
						&& ord.getOrderStatus() == null) {
					ordList.add(ord);
				}
			}
			Collections.sort(ordList, sortby);
			return ordList;
		} catch (NullPointerException ne) {
			log.warn(EMPTY_COLLEC);
			throw new RuntimeException(NOT_ORDER);
		}

	}


	public static ArrayList<IOrder> SortOrder(ArrayList<IOrder> orderList, Comparator sortBy) {
		if(!orderList.isEmpty()){
			Collections.sort(orderList, sortBy);
			return orderList;
		} else {
			log.warn(EMPTY_COLLEC);
			throw new RuntimeException(NOT_ORDER);
		}
	}
	

	public static String getNextFreeDate(ArrayList<IOrder> orderList) {
		if(!orderList.isEmpty()){
			Collections.sort(orderList, new SortOrderByDeadlineDate());
			GregorianCalendar date=new GregorianCalendar();
			Date temp = orderList.get(0).getDeadlineDate();
			date.setTime(temp);
			date.set(Calendar.DAY_OF_YEAR, 1);
			temp=date.getTime();			
			return format.format(temp.getTime());
		} else {
			log.warn(EMPTY_COLLEC);
			throw new RuntimeException(NOT_ORDER);
		}
	}

	
	public static ArrayList<IOrder> getOrderByPeriod(ArrayList<IOrder> orderList,
			Comparator sortby, OrderStatus ordSt, Date begin,
			Date end) {
		if(!orderList.isEmpty()) {
			ArrayList<IOrder> ordList = new ArrayList<IOrder>();

			for (IOrder ord : orderList) {
				if ((ord.getBeginingDate().after(begin) && ord
						.getBeginingDate().before(end))
						&& ord.getOrderStatus() == ordSt) {
					ordList.add(ord);
				}
			}
			if (ordList.isEmpty()) {
				throw new RuntimeException(ORD_STAT_NOT_FOUND);
			} else {
				Collections.sort(ordList, sortby);
				return ordList;
			}
		} else {
			log.warn(EMPTY_COLLEC);
			throw new RuntimeException(NOT_ORDER);
		}
	}

	
	public static void addOrder(ArrayList<IOrder> orderList, IOrder order,
			ArrayList<IMaster> masList, ArrayList<IGarage> garList,
			String masterName, Integer numberGarage) {

		for (IOrder o : orderList) {
			if (o.getNumberOrder() == order.getNumberOrder()) {
				order.setNumberOrder(orderList.size() + 1);
				throw new RuntimeException(ORD_EXISTS + order.getNumberOrder());

			}
		}
		orderList.add(order);
		
		IMaster master = null;
		IGarage garage = null;
		for (IMaster m : masList) {
			if (m.getNameMaster().equals(masterName)) {
				master = m;
			}
		}

		for (IGarage g : garList) {
			if (g.getNumberGarage() == numberGarage) {
				garage = g;
			}
		}
		order.sendMasterGarage(master, garage);

	}

	public static void markOrder(ArrayList<IOrder> orderList,
			OrderStatus ordSt, Integer orderNumber) {
		if(!orderList.isEmpty()) {
			int i = 0;
			for (IOrder o : orderList) {
				if (o.getNumberOrder() == orderNumber) {
					o.setOrderStatus(ordSt);
					o.getMaster().markMasterFree();
					o.getGarage().markGarageEmpty();
					i++;
				}
			}
			if (i == 0) {
				throw new RuntimeException(ORD_NOT_EXISTS);
			} 
		} else {
			log.warn(EMPTY_COLLEC);
			throw new RuntimeException(NOT_ORDER);
		}
	}

	
	public static void ShirtTimeOrder(ArrayList<IOrder> orderList,
			Date newDate, Integer numberOrder) {
		if(!orderList.isEmpty()){
			int i=0;
			for (IOrder ord : orderList) {
				if (ord.getNumberOrder() == numberOrder) {
					ord.shiftTime(newDate);
					i++;
				}
			}
			if(i==0){
				throw new RuntimeException(ORD_NOT_EXISTS);
			}
		} else {
			log.warn(EMPTY_COLLEC);
			throw new RuntimeException(NOT_ORDER);
		}
	}

	public static IOrder cloneOrder(IOrder order) {
		try {
			IOrder clone = order.cloneOrder();
			return clone;
		} catch (CloneNotSupportedException e) {
			log.error(EXCEPTION_CLONE);
			throw new RuntimeException(EXCEPTION_CLONE);
		}
	}

}
